Putting our data to use

The previous session went through the flow sheet for the Data Acquisition phaze. 
Now we need to step through the Data Processing and Data Display phazes.
The process and display activities are so intertwined, they are covered together.

In Review of the acquisition process, we loaded the z() array with data that is
to be presented for examination and possible editing. We took the flow of processes
from program start to waiting for interaction at the SHOWMODAL.

Three subs were noted, but not explored during the acquisition process in the xRestore Sub.
xOFFSET  posts the relative address into the eOFFSET QRichedit Object.
xHEX     posts the Icon File Data  bytes to the eHEX QRichEdit Object.
xPost    displays the graphics necessary to interactively Edit        
 
 Sub xRestore
         xoffset
         xhex
      IF eoz <> 765 then showmessage " this is not a 766 byte file"_
         +chr$(13)+"the graphics display will be other"_
         +chr$(13)+"then that of a RapidQ .ico file"
     xpost
 end sub

First we will discuss the xOFFSET and xHEX routines, followed by the xPOST routine.

xOFFSET
I could have simply posted addresses, 16 bytes per line. 
But I couldn't resist breaking up the display as one parameter per line for appearance. 
It looks better too.
First, the QRichedit ascii field is cleared. If no z() data, then exit the sub.
Next, the Read Only flag is cleared so we can write ascii data.
Then the offset for the first 11 parameters of the Icon file are given their own line.

FOR-NEXT loops post the lines for the hex display of 16 bytes per line. 
The blocks of data in the eHEX ascii display are seperated with a blank line, so they must appear here as well. 
You may be wondering why four spaces are used to generate a blank line. 
This is done so that each line in this display will consist of the same number of bytes per line of text. 
I want to be able to locate a line number arithmetically for a later function.
Its completed by turning the Read Only flag ON so text can't be entered from the keyboard. 
Its now fixed.
We either exited with the EXIT SUB directive or will exit now with EXIT SUB.
The program will return to the xRESTORE sub and swallow the RETURN ADDRESS properly.


eHEX
the next sub in xRESTORE, immediately following eOFFSET. 
It will write the ascii bytes to the eHEX display along side the address offsets.
The ascii text field is cleard and the sub is exited if z() holds no bytes to display.
This is actually two sub routines, the POSTARRAY sub is called to post block of data.
     POSTARRAY posts data from the z() array using two glogal parameters, go and stop. 
     go defines where to begin and stop defines where to stop.
     two each byte is posted seperated by a space, 16 bytes per line.
Occasional blank lines are inserted to correspond with the eOFFSET display.
This keeps everything alligned for viewing and the different blocks of data identified.

You may have noticed that the eHEX display uses automatic line wrap after 16 bytes.
I can locate a particular byte arithmetically without skipping carriage return- line feeds. 
It also dictates that the FONT size be compatable with the eHEX width property.
Just a heads up if you decide to use a different FONT or FONT.size.

All RETURN ADDRESSES on the stack are properly swallowed from the POSTARRY sub.
The EXIT SUB swallows this sub's RETURN ADDRESS and program execution returns to sender.
On Program Start-up, this returns execution to the xRESTORE sub.


xNewz
Although is it not part of the start-up sequence it is part of the File handlers.
It is part of the File Save routine. I have done things a little left handed here.
Normally, processing would be done from the z() array data bytes, but I have elected to
put operate from the the data in the eHEX ascii field instead. The reason for doing this 
is to permit editing these data easily by simply changing the ascii data in the eHEX display. 
You could write your own Machine Language Program in the eHEX field and save it to disk.
This module converts the ascii bytes to hex bytes in z() and outputs is to the disk.

The reason for this will becom clear in the xPOST modules later.
However; by doing this, its necessary to convert the edited data back into the 
z() array prior to saving it to disk. This sub routine accomplishes this.
It also requires a good bit of explaination as well. Here is the walk-through:


Firstly intex n is zeroed. Then the entire eHEX ascii data is loaded into variable C$.
        notice that C$ ascii will be upper case, if you use lower case in eHEX.

variable C is used to index through C$ using a FOR-NEXT loop.
variable msb$ captures the first character in C$. It is a byte's most significant nibble.
         however; it its a space, then is skilled over and C is incremented.
  IF it is a valid digit, then the two character ascii byte gets serviced.
     it is converted to a number using the INSTR( ) function into numeric variable msb.
        INSTR() returns the ascii characters location in HX$. Minus 1 is its numeric value.
     lsb$ and lsb are treated the same way with location c+1
     The byte is loaded with the bytes value by summing the calculated lsb and msb nibbles.
     The c$ index is incremented by one because two nibles were serviced.
     the variable n, the z() is incremented at this time.
 NEXT C  increments c again, past the space or for the ascii HEX nibbles.
     When the entire C$ string has been serviced, eoz is set to the z() array length.
     This ensures that those number of bytes in eHEX will be SAVED to the disk.
 
These few lines of code do quite a task. If you make any changes in it, be sure to SAVE
your data to disk and check it often. It can easily be tested using the HEX editor we 
made in the last project. Its time consuming, but it will save a lot of compounded 
errors in calculating.



 
These support subs for the data file's input and output functions doesn't take a lot of 
coding. The QObjects takes all the leg work out of it. We did get a little wiggle room 
to play around with the memory management though. These modules and what they do are 
extremely important with later processing and display routines. Feeling comfortable with 
these modules makes further development much easier. Maintaining duplicated data is not 
only a waste of time, but it is also the source of many bugs that hide themselves until 
a program is used in an unusual sequence of calls.
 

Softalk

It took several sessions to get here with the program. It probably all seems pretty 
straight forward by now. And... there is a lot more code to cover.
However; now that the basic structure of memory has been establishes, the processing 
and display section becomes rather fun. A new idea, play with it and see if you wish 
to encorporate it into your final program. This is where artists license shows itself.

The processing and display phaze of a program is extremely important. Interaction with 
the operatore determines whether a program is labeled "User Friendly" or not. If you 
find a sequence of events uncomfortable, take the time to make is comfortable for you.
That is one of the chief adfantages of being able to code you own programs.

Happy Hacking.